{
 "cells": [
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# The SVD as an eigenproblem\n",
    "\n",
    "Notice that if $A = U\\Sigma V^H$, then\n",
    "\n",
    "$$\n",
    "A^H A = V \\Sigma U^H U \\Sigma V^H = V \\Sigma^2 V^H\n",
    "$$\n",
    "\n",
    "That is, to multiply $A^H A x$, you (1) compute $V^H x$ (the $V$ components of $x$), then (2) multiply each component by $\\sigma^2$, and finally (3) multiply the coefficients by $V$ and add up.  It follows that:\n",
    "\n",
    "* The singular values $\\sigma^2$ are the **nonzero eigenvalues** of $A^H A$ and the corresponding **eigenvectors are the right singular vectors** $V$.\n",
    "\n",
    "Similarly,\n",
    "\n",
    "$$\n",
    "A A^H = U \\Sigma V^H V \\Sigma U^H = U \\Sigma^2 U^H\n",
    "$$\n",
    "\n",
    "so\n",
    "\n",
    "* The singular values $\\sigma^2$ are the **nonzero eigenvalues** of $A A^H$ and the corresponding **eigenvectors are the left singular vectors** $U$.\n",
    "\n",
    "We can easily check this:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 1,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "5×3 Array{Float64,2}:\n",
       "  0.202935  -0.810741  0.379812 \n",
       "  0.317852   1.17222   0.0789665\n",
       " -1.58283   -0.524304  0.949145 \n",
       "  0.122448   1.57466   0.693527 \n",
       " -0.496476   1.13621   0.511883 "
      ]
     },
     "execution_count": 1,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "A = randn(5,3)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Note that in this case, $A$ is a $5 \\times 3$ matrix of rank 3."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 2,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "3-element Array{Float64,1}:\n",
       " 6.31957 \n",
       " 4.01707 \n",
       " 0.443596"
      ]
     },
     "execution_count": 2,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "U, σ, V = svd(A)\n",
    "\n",
    "σ.^2    # the σ² values"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "$A^H A$ is a $3 \\times 3$ matrix of rank 3 with three nonzero eigenvalues that equal the singular values squared:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 3,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "3-element Array{Float64,1}:\n",
       " 0.443596\n",
       " 4.01707 \n",
       " 6.31957 "
      ]
     },
     "execution_count": 3,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "eigvals(A'*A) # AᴴA has the same eigenvals!"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "$AA^H$ is a $5 \\times 5$ matrix of rank 3 (recall that the ranks of $A$, $AA^H$, and $A^H A$ are all equal!).   It has 3 nonzero eigenvalues that equal the $\\sigma^2$ values, and 2 zero eigenvalues corresponding to the **two-dimensional** nullspace\n",
    "$$\n",
    "N(AA^H) = N(A^H) = C(A)^\\perp = C(U)^\\perp\n",
    "$$\n",
    "That is, the zero eigenvectors are those perpendicuar to the left singular vectors $U$."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 4,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "5-element Array{Float64,1}:\n",
       " -1.71137e-16\n",
       "  8.87578e-16\n",
       "  0.443596   \n",
       "  4.01707    \n",
       "  6.31957    "
      ]
     },
     "execution_count": 4,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "eigvals(A*A') # the same *nonzero* eigenvalues"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "We can also check the eigenvectors, e.g. the eigenvectors of $A^H A$ should match V:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 5,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "3×3 Array{Float64,2}:\n",
       "  0.564298  -0.817673    0.113922\n",
       " -0.203239  -0.00384465  0.979122\n",
       "  0.800163   0.57567     0.168353"
      ]
     },
     "execution_count": 5,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "eigvecs(A'A)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 6,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "3×3 Array{Float64,2}:\n",
       " -0.113922  -0.817673    -0.564298\n",
       " -0.979122  -0.00384465   0.203239\n",
       " -0.168353   0.57567     -0.800163"
      ]
     },
     "execution_count": 6,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "V"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Yes, they match, up to an overall sign flip.\n",
    "\n",
    "(Note that the columns are in reverse order, because `svdvals` are by default sorted in *descending* order in Julia, whereas `eigvals` of Hermitian matrices are sorted in *ascending* order.)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Remarks\n",
    "\n",
    "* This, in principle, finally gives us a way to compute the SVD of a matrix: just find the eigenvectors and eigenvalues of $A^H A$.  (Note that $AV = U\\Sigma$, so that once you have $V$ and $\\Sigma$ you can get $U$.)\n",
    "\n",
    "* In practice, computers use a different way to compute the SVD.  (The most famous practical method is called \"Golub-Kahan bidiagonalization.\")  In 18.06, we are content to let the `svd` function be a \"black box\", much like `eig`.\n",
    "\n",
    "* The fact that the singular values/vectors are related to eigenvalues of $A^H A$ and $A A^H$ has lots of important applications.  Perhaps most famously, it means that the SVD diagonalizes the \"covariance matrix\" in statistics, which gives rise to the statistical method of [principal component analysis (PCA)](https://en.wikipedia.org/wiki/Principal_component_analysis)."
   ]
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "Julia 0.6.3",
   "language": "julia",
   "name": "julia-0.6"
  },
  "language_info": {
   "file_extension": ".jl",
   "mimetype": "application/julia",
   "name": "julia",
   "version": "0.6.3"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 2
}
